﻿using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Niti.OrderManage.Application.Contracts;
using Niti.OrderManage.DTO;
using Niti.OrderManage.Eto;
using Niti.OrderManage.OrderManage;
using Niti.OrderManage.OrderManage.Repositories;
using Niti.OrderManage.ToolKits.Base;
using Niti.OrderManage.ToolKits.Extensions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Volo.Abp;
using Volo.Abp.Domain.Entities.Events;
using Volo.Abp.EventBus;
using Volo.Abp.EventBus.Distributed;
using Volo.Abp.EventBus.Local;
using static Niti.OrderManage.NitiOrderManageConsts;

namespace Niti.OrderManage.Order.Impl
{
    [ApiController]
    [Route("[controller]")]
    [ApiExplorerSettings(GroupName = Grouping.GroupName_v2)]
    public class CommodityService: NitiOrderManageApplicationServiceBase,
          ILocalEventHandler<OrderCommodityEto>,
          ILocalEventHandler<CheckedCommodityCountEto>
    {

        private readonly ICommodityRepository _commodityRepository;
        private readonly ILogger _logger;
        private readonly ILocalEventBus _localEventBus;

        public CommodityService(ICommodityRepository commodityRepository, 
            ILogger<CommodityService> logger,
            ILocalEventBus localEventBus
            )
        {
            _commodityRepository = commodityRepository;
            _logger = logger;
            _localEventBus = localEventBus;
        }


        /// <summary>
        /// 新增商品
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<ServiceResult<string>> InsertCommodityAsync(CommodityDto dto)
        {
            var result = new ServiceResult<string>();
            try
            {
                //查询是否有该商品
                var entityExist = await _commodityRepository.FindAsync(x=>x.Code==dto.Code&&x.IsDeleted==false);
                if (entityExist != null)
                {
                    result.IsFailed(ResponseText.INSERT_FAILED + ",已存在该商品");
                    return result;
                }

                //var entity = ObjectMapper.Map<CommodityDto, Commodity>(dto);
                var entity = new Commodity(dto.Code,dto.CName,dto.CPrice);

                var post = await _commodityRepository.InsertAsync(entity);
                if (post == null)
                {
                    result.IsFailed(ResponseText.INSERT_FAILED);
                    return result;
                }

                result.IsSuccess(ResponseText.INSERT_SUCCESS);

            }
            catch (Exception ex)
            {
               _logger.LogError(ex.ToString());
                result.IsFailed(ResponseText.INSERT_FAILED);
            }

            return result;
        }
        /// <summary>
        /// 删除商品
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpDelete]
        public async Task<ServiceResult> DeleteCommodityAsync(int id)
        {
            ServiceResult result = new ServiceResult();
            try
            {
                var Commodity = await _commodityRepository.FindAsync(x=>x.Id==id && x.IsDeleted==false);
                if (Commodity == null)
                {
                    result.IsFailed(ResponseText.WHAT_NOT_EXIST.FormatWith("Id", id));
                    return result;
                }

                Commodity.IsDeleted = true;
                Commodity.DeleteTime = DateTime.Now;
                await _commodityRepository.DeleteAsync(Commodity);
                result.IsSuccess(ResponseText.DELETE_SUCCESS);


            }
            catch (Exception ex)
            {
               _logger.LogError(ex.ToString());
                result.IsFailed(ResponseText.DELETE_FAILED);
            }

            return result;
        }
        /// <summary>
        /// 更新商品
        /// </summary>
        /// <param name="id"></param>
        /// <param name="dto"></param>
        /// <returns></returns>
        [HttpPut]
        public async Task<ServiceResult<string>> UpdateCommodityAsync(int id, CommodityDto dto)
        {
            var result = new ServiceResult<string>();
            try
            {
                var Commodity = await _commodityRepository.FindAsync(x=>x.Id==id&&x.IsDeleted==false);
                if (Commodity == null)
                {
                    result.IsFailed(ResponseText.WHAT_NOT_EXIST.FormatWith("Id", id));
                    return result;
                }

                //var entity = ObjectMapper.Map<CommodityDto, Commodity>(dto);

                #region 映射
                Commodity.CName = dto.CName;
                Commodity.CPrice = dto.CPrice;
                Commodity.UpdateTime = dto.UpdateTime;
                #endregion

                var post = await _commodityRepository.UpdateAsync(Commodity);
                if (post == null)
                {
                    result.IsFailed(ResponseText.UPDATE_FAILED);
                    return result;
                }

                result.IsSuccess(ResponseText.UPDATE_SUCCESS);


            }
            catch (Exception ex)
            {
               _logger.LogError(ex.ToString());
                result.IsFailed(ResponseText.UPDATE_FAILED);
            }
            return result;


        }
        /// <summary>
        /// 根据id查询商品
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpGet]
        public async Task<ServiceResult<CommodityDto>> GetCommodityAsync(int id)
        {
            ServiceResult<CommodityDto> result = new ServiceResult<CommodityDto>();
            try
            {
                var entity = await _commodityRepository.GetAsync(x=>x.Id==id&&x.IsDeleted==false);
                if (entity == null)
                {
                    result.IsFailed(ResponseText.WHAT_NOT_EXIST.FormatWith("Id", id));
                    return result;
                }

                result.IsSuccess("ok");
                // var dto = ObjectMapper.Map<Commodity,CommodityDto>(entity);
                var dto = new CommodityDto()
                {
                    Code = entity.Code,
                    CName = entity.CName,
                    CPrice = entity.CPrice,
                    CreationTime = entity.CreationTime,
                    UpdateTime = entity.UpdateTime,
                    DeleteTime = entity.DeleteTime
                };
                result.Result = dto;

            }
            catch (Exception ex)
            {
                result.IsFailed(ResponseText.WHAT_NOT_EXIST.FormatWith("Id", id));
               _logger.LogError(ex.ToString());
            }
            return result;
        }


        /// <summary>
        /// 分页查询
        /// </summary>
        /// <param name="pageIndex">页码</param>
        /// <param name="pageSize">条数</param>
        /// <param name="name">名称</param>
        /// <param name="code">编号</param>
        /// <returns></returns>
        [HttpGet]
        [Route("CommodityList")]
        public async Task<ServiceResult<PagedList<CommodityDto>>> GetCommodityListAsync(int pageIndex = 1, int pageSize = 10, string name = "", string code = "")
        {
            var result = new ServiceResult<PagedList<CommodityDto>>();
            try
            {

                var list = (from Commoditys in await _commodityRepository.GetListAsync()
                            where (string.IsNullOrEmpty(name) || Commoditys.CName.Contains(name))
                                  && (string.IsNullOrEmpty(code) || Commoditys.Code == code)
                                  && Commoditys.IsDeleted == false
                            orderby Commoditys.CreationTime descending
                            select new CommodityDto
                            {
                                Code = Commoditys.Code,
                                CName = Commoditys.CName,
                                CPrice = Commoditys.CPrice,
                                UpdateTime = Commoditys.UpdateTime,
                                DeleteTime = Commoditys.DeleteTime,
                                CreationTime = Commoditys.CreationTime,
                            }).OrderByDescending(m => m.CreationTime).Skip(pageSize * (pageIndex - 1)).Take(pageSize).ToList();

                result.IsSuccess(new PagedList<CommodityDto>(list.Count, list));

            }
            catch (Exception ex)
            {
               _logger.LogError(ex.ToString());
                result.IsFailed("查询失败");
            }

            return result;
        }


        #region 订阅事件
        /// <summary>
        /// 订阅采购单校验商品
        /// </summary>
        /// <param name="eventData"></param>
        /// <returns></returns>
        [NonAction]
        public async Task HandleEventAsync(OrderCommodityEto eventData)
        {
            try
            {
                //如果存在订单包含该商品，
                var entity = await _commodityRepository.FindAsync(x => x.Code == eventData.Commodity.Code&& x.IsDeleted == false);
                if (entity == null)
                    throw new NotImplementedException("不存在该商品或者该商品已下架");
                if(entity.CName!=eventData.Commodity.CName||entity.CPrice!=eventData.Commodity.CPrice)
                    throw new NotImplementedException("不存在该商品或者该商品已下架");
                eventData.Count = entity.Count;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex.ToString());
                throw new NotImplementedException(ex.ToString());
            }
            await Task.CompletedTask;
        }

        /// <summary>
        /// 订阅入库单/出库单商品数量变化
        /// </summary>
        /// <param name="eventData"></param>
        /// <returns></returns>
        [NonAction]
        public async Task HandleEventAsync(CheckedCommodityCountEto eventData)
        {
            try
            {
                var list = _commodityRepository.Where(x => eventData.Dic.Keys.Contains(x.Code)).OrderBy(x => x.Code).ToList();
                foreach (var commodity in list)
                {
                    commodity.Count += eventData.Dic[commodity.Code];
                }
                await _commodityRepository.UpdateManyAsync(list);

            }
            catch (Exception ex)
            {
                _logger.LogError(ex.ToString());
                throw new NotImplementedException(ex.ToString());
            }
        }
      
        #endregion




        #region 废弃
        ///// <summary>
        ///// 根据名称分页查询
        ///// </summary>
        ///// <param name="input"></param>
        ///// <param name="name"></param>
        ///// <returns></returns>
        //[HttpPost]
        //[Route("CommodityListByName")]
        //public async Task<ServiceResult<PagedList<CommodityDto>>> GetCommodityListByNameAsync(PagingInput input, string name = "")
        //{
        //    var result = new ServiceResult<PagedList<CommodityDto>>();
        //    try
        //    {
        //        if (string.IsNullOrEmpty(name))
        //        {

        //            var list = _commodityRepository
        //                                  .Where(x => x.IsDeleted == false)
        //                                  .OrderByDescending(x => x.CreationTime)
        //                                  .PageByIndex(input.Page, input.Limit)
        //                                  .Select(x => new CommodityDto
        //                                  {
        //                                      Code = x.Code,
        //                                      CName = x.CName,
        //                                      CPrice = x.CPrice,
        //                                      UpdateTime = x.UpdateTime,
        //                                      DeleteTime = x.DeleteTime,
        //                                      CreationTime = x.CreationTime,
        //                                  })
        //                                  //.Select(x => ObjectMapper.Map<Commodity, CommodityDto>(x))
        //                                  .ToList();

        //            result.IsSuccess(new PagedList<CommodityDto>(list.Count, list));
        //        }
        //        else
        //        {
        //            var list = (from Commoditys in await _commodityRepository.GetListAsync()
        //                        where Commoditys.CName.Contains(name) && Commoditys.IsDeleted == false
        //                        orderby Commoditys.CreationTime descending
        //                        select new CommodityDto
        //                        {
        //                            Code = Commoditys.Code,
        //                            CName = Commoditys.CName,
        //                            CPrice = Commoditys.CPrice,
        //                            UpdateTime = Commoditys.UpdateTime,
        //                            DeleteTime = Commoditys.DeleteTime,
        //                            CreationTime = Commoditys.CreationTime,
        //                        }).OrderByDescending(m => m.CreationTime).Skip(input.Limit * (input.Page - 1)).Take(input.Limit).ToList();
        //            result.IsSuccess(new PagedList<CommodityDto>(list.Count, list));
        //        }

        //    }
        //    catch (Exception ex)
        //    {
        //       _logger.LogError(ex.ToString());
        //        result.IsFailed("查询失败");
        //    }

        //    return result;
        //}

        ///// <summary>
        ///// 根据编号分页查询
        ///// </summary>
        ///// <param name="input"></param>
        ///// <param name="code"></param>
        ///// <returns></returns>
        //[HttpPost]
        //[Route("CommodityListByCode")]
        //public async Task<ServiceResult<PagedList<CommodityDto>>> GetCommodityListByCodeAsync(PagingInput input, string code = "")
        //{
        //    var result = new ServiceResult<PagedList<CommodityDto>>();
        //    try
        //    {
        //        if (string.IsNullOrEmpty(code))
        //        {

        //            var list = _commodityRepository
        //                                  .Where(x => x.IsDeleted == false)
        //                                  .OrderByDescending(x => x.CreationTime)
        //                                  .PageByIndex(input.Page, input.Limit)
        //                                  .Select(x => new CommodityDto
        //                                  {
        //                                      Code = x.Code,
        //                                      CName = x.CName,
        //                                      CPrice = x.CPrice,
        //                                      UpdateTime = x.UpdateTime,
        //                                      DeleteTime = x.DeleteTime,
        //                                      CreationTime = x.CreationTime,
        //                                  })
        //                                  //.Select(x => ObjectMapper.Map<Commodity, CommodityDto>(x))
        //                                  .ToList();

        //            result.IsSuccess(new PagedList<CommodityDto>(list.Count, list));
        //        }
        //        else
        //        {
        //            var list = (from Commoditys in await _commodityRepository.GetListAsync()
        //                        where Commoditys.CName.Contains(code) && Commoditys.IsDeleted == false
        //                        orderby Commoditys.CreationTime descending
        //                        select new CommodityDto
        //                        {
        //                            Code = Commoditys.Code,
        //                            CName = Commoditys.CName,
        //                            CPrice = Commoditys.CPrice,
        //                            UpdateTime = Commoditys.UpdateTime,
        //                            DeleteTime = Commoditys.DeleteTime,
        //                            CreationTime = Commoditys.CreationTime,
        //                        }).OrderByDescending(m => m.CreationTime).Skip(input.Limit * (input.Page - 1)).Take(input.Limit).ToList();
        //            result.IsSuccess(new PagedList<CommodityDto>(list.Count, list));
        //        }

        //    }
        //    catch (Exception ex)
        //    {
        //       _logger.LogError(ex.ToString());
        //        result.IsFailed("查询失败");
        //    }


        //    return result;
        //}

        #endregion

    }
}
